package zip

import (
	"errors"
	"fmt"
	"log"

	"fish-scaner/adl"
	"fish-scaner/binary"

	"github.com/gogf/gf/encoding/gcompress"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/text/gregex"
	"github.com/gogf/gf/util/gconv"
	"github.com/gogf/gflock"
)

func Zip(workDir, fishdb, systematics, willZipDirName string,
	// stdOutCh chan string,

	ws *ghttp.WebSocket,
	stdErrCh chan error,

) { // inf string, err error,

	fmt.Println(workDir+`tmp_files/`+fishdb+`/`+systematics, willZipDirName+`*`, false)

	dirName := ScanDir(workDir+`tmp_files/`+fishdb+`/`+systematics, willZipDirName+`*`, false, ws)
	fmt.Println(`------------------------------compress--------------------------------`)
	// ws.SentWithFlag(`stdOut`, `开始打包文件夹`+dirName)
	if err := ws.WriteMessage(1, adl.SentWithFlag(`stdOut`, `开始打包文件夹`+dirName)); err != nil {
		glog.Println(`ws sent err:`, err, `!`)
	}
	var compressDir string
	if systematics == `ke` {
		// keJson:=binary.Binary[`ke.json`].Bytes()
		// gjson.Decode(keJson)
		compressDir = `zip_files/` + fishdb + `_` + gconv.String(binary.Jsons[`ke`][willZipDirName]) + `.zip`
	} else if len(gfile.Basename(dirName)) == 1 || gfile.Basename(dirName) == `.` {
		compressDir = `zip_files/` + fishdb + `_` + willZipDirName + `属.zip`
	} else {
		fmt.Println(gfile.Basename(dirName), `:`, len(gfile.Basename(dirName)))
		compressDir = `zip_files/` + fishdb + `_` +
			gfile.Basename(dirName) + `属.zip`
	}
	fmt.Println(`------------------------------` + compressDir + `--------------------------------`)
	fmt.Println(`------------------------------` + dirName + `--------------------------------`)
	fileLock := gflock.New(workDir + `tmp_files/` + compressDir)

	if fileLock.IsLocked() {
		// r.Response.WriteJsonExit(stringJson{
		// `sorry`: `压缩包正在打包中`,
		// })
		if err := ws.WriteMessage(1, adl.SentWithFlag(`sorry`, `压缩包正在打包中`)); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
			stdErrCh <- errors.New(``)
			return
		}
		// glog.Panic()
	}

	for {

		if !fileLock.IsRLocked() {
			break
			// glog.Println(`wait)
		}
		if err := ws.WriteMessage(1, adl.SentWithFlag(`sorry`, `文件正在被下载, 等待写入中`)); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
		}
	}

	lockErr := fileLock.Lock()
	if lockErr != nil {
		if err := ws.WriteMessage(1, adl.SentWithFlag(`sorry`, `文件加锁失败: `+lockErr.Error())); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
		}
		glog.Println(lockErr)
		stdErrCh <- lockErr
		return
		// glog.Panic(lockErr)
	}
	rlockErr := fileLock.RLock()
	if rlockErr != nil {
		if err := ws.WriteMessage(1, adl.SentWithFlag(`sorry`, `文件加锁失败: `+rlockErr.Error())); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
		}
		glog.Println(rlockErr)
		stdErrCh <- rlockErr
		return
		// glog.Panic(lockErr)
	}
	err := gcompress.ZipPath( /*`/root/object/rzh/tmp_files/fishdb/`+*/ dirName, workDir+`tmp_files/`+compressDir)
	lockErr = fileLock.Unlock()
	if lockErr != nil {
		glog.Println(err)
	}
	rlockErr = fileLock.RUnlock()
	if rlockErr != nil {
		glog.Println(err)
	}

	if err != nil {
		log.Println(`compress err: `, err)
		// ws.SentWithFlag(`stdOut`, `压缩失败: `+err.Error())
		if err := ws.WriteMessage(1, adl.SentWithFlag(`stdOut`, `压缩失败: `+err.Error())); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
			return
		}
		stdErrCh <- err
		log.Fatalln(`------------------------------ compress fail --------------------------------`)
		// stdOutCh <- ``
		return
		// return ``, err
	}
	fmt.Println(`------------------------------ compress success--------------------------------`)
	// ws.SentWithFlag(`stdOut`, `压缩完成`)
	// ws.SentWithFlag(`download`, compressDir)
	if err := ws.WriteMessage(1, adl.SentWithFlag(`download`, compressDir)); err != nil {
		glog.Println(`ws sent err:`, err, `!`)
		return
	}
	stdErrCh <- nil
	fmt.Println(`------------------------------ stderr success--------------------------------`)
	// stdOutCh <- compressDir
	// fmt.Println(`------------------------------ stdout success--------------------------------`)
	// return compressDir, nil
}

func ScanDir(dir, file string, recursive bool, ws *ghttp.WebSocket) string {
	// ws.SentWithFlag(`stdOut`, `在 `+workDir+`tmp_files/`+fishdb+`/`+systematics+`中搜索`+willZipDirName+`*`)
	fmt.Println(`------------------------------ scan dir --------------------------------`)
	fmt.Println(`find`, file, `from`, dir+`/`+file, recursive)
	scanResult, err := gfile.ScanDir(dir, file, recursive)
	if err != nil {
		// ws.SentWithFlag(`stdOut`, err.Error())
		if err := ws.WriteMessage(1, adl.SentWithFlag(`stdOut`, err.Error())); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
		}
		// stdErrCh <- err
		// stdOutCh <- ``
		// log.Fatalln(err)
		log.Println(err)
		// return ``
		// return ``, err
	}
	var dirName string
	for _, dirName = range scanResult {
		fmt.Println(dirName)
		// log.Println(gfile.Basename(dirName))
	}

	if recursive {
		fmt.Println(`------------------------------ scan dir finished --------------------------------`)
		scanResult, err := gfile.ScanDir(dirName, `*.*g`, true)
		if err != nil {
			// ws.SentWithFlag(`stdOut`, err.Error())

			if err := ws.WriteMessage(1, adl.SentWithFlag(`stdOut`, err.Error())); err != nil {
				glog.Println(`ws sent err:`, err, `!`)
			}
			// stdErrCh <- err
			// stdOutCh <- ``
			log.Println(err)
			// log.Fatalln(err)
			return ``
			// return ``, err
		}
		glog.Println(scanResult)
		// ws.SentWithFlag(`showImg`, scanResult)
		infBack := make([]string, 0)
		i := 1
		for _, imgName := range scanResult {
			if i > 3 {
				break
			}
			// infBack = append(infBack, `https://rzh.seafishery.com/`++gfile.Basename(imgName))
			url, _ := gregex.ReplaceString(`/root/object/rzh/tmp_files`, `https://rzh.seafishery.com`, imgName)
			infBack = append(infBack, url)
			i++
		}
		if err := ws.WriteMessage(1, adl.SentWithFlag(`showImg`, infBack)); err != nil {
			glog.Println(`ws sent err:`, err, `!`)
		}
		return ``

	}
	// ws.SentWithFlag(`scanDir`, err.Error())

	return dirName
}
